package com.tas.movies.formats
{
	import com.tas.movies.Movie;
	import com.tas.movies.MovieFrame;
	import com.tas.movies.MovieProperty;
	
	import flash.events.Event;

	public class SNES9x extends Movie
	{
		public function SNES9x()
		{
			super();
			
			setDataType( DATA_BYTES, 2 );
			
			controllerMap = [ ">", "<", "v", "^", 
							  "S", "s", "Y", "B", 
							  "R", "L", "X", "A" ];
		}								
		
		/**
		 * @inheritDoc
		 */		
		override protected function loadProperties( e:Event=null ) : void
		{
			var saveOffset  : uint;
			var syncOptions : MovieProperty;
			var controllers : MovieProperty;
			
			// parse header
			
			registerProperty( "signature", 4, MovieProperty.TYPE_BIG_ENDIAN );
			registerProperty( "version", 4 );
			registerProperty( "timestamp", 4 );
			registerProperty( "rerecord_count", 4 );
			registerProperty( "frame_count", 4 );
			
			controllers = registerProperty( "controller_mask", 1, MovieProperty.TYPE_FLAGS );
			
			registerProperty( "movie_options", 1, MovieProperty.TYPE_FLAGS );
			registerProperty( "reserved0", 1 );
			
			syncOptions = registerProperty( "sync_options", 1, MovieProperty.TYPE_FLAGS );			
			saveOffset  = registerProperty( "savestate_offset", 4 ).getValue();
			
			registerProperty( "controller_data_offset", 4 );						
			
			if( syncOptions.getFlag(6) ){
				registerProperty( "author", saveOffset - fileSeekPointer - 30, MovieProperty.TYPE_UTF16_STRING );
				registerProperty( "padding", 3 );
				registerProperty( "rom_crc", 4, MovieProperty.TYPE_BIG_ENDIAN );
				registerProperty( "rom_name", 23, MovieProperty.TYPE_UTF8_STRING );	
			}else{
				registerProperty( "author", saveOffset - fileSeekPointer, MovieProperty.TYPE_UTF16_STRING );
			}						
			
			// parse controllers
			
			var count : int = 0;
			for( var i:int = 0; i < 4; i++ ){
				if( controllers.getFlag(i) ){
					count++;
					activeControllers[i] = true;
				}
			}
			
			setControllerCount( count );
			
			super.loadProperties();
		}
		
		private var _readPosition : uint = 0;
		
		/**
		 * @inheritDoc
		 */		
		override protected function loadFrames( e:Event=null ) : void
		{			
			super.loadFrames();
						
			_readPosition = getProperty( "controller_data_offset" ).getValue();
						
			chunker.length = frameCount + 1;
			chunker.setHandler( readSMVFrame );
			chunker.start();								
		}
		
		/**
		 * @private
		 * 
		 * <code>Chunker</code> process loop for reading
		 * SNES9x movie data
		 *  
		 * @param position		 
		 */		
		private function readSMVFrame( position:uint ) : void
		{
			var frame : MovieFrame = new MovieFrame();
			for( var j:int = 0; j < numControllers; j++ ){
				var d : uint = rawMovie[_readPosition] | rawMovie[_readPosition + 1];
				frame.setController( j, readFrame(d) );
				_readPosition += 2;
			}
			frames.addItem( frame );
		}
		
						
	}
}